CREATE TABLE public.lugares (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  nombre text NOT NULL CHECK (nombre = TRIM(BOTH FROM nombre)),
  direccion text,
  url_google_maps text,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'INACTIVO'::text])),
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  updated_at timestamp with time zone NOT NULL DEFAULT now(),
  CONSTRAINT lugares_pkey PRIMARY KEY (id)
);
CREATE TABLE public.sedes (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  nombre text NOT NULL UNIQUE,
  lugar_id uuid NOT NULL UNIQUE,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'INACTIVO'::text])),
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  updated_at timestamp with time zone NOT NULL DEFAULT now(),
  CONSTRAINT sedes_pkey PRIMARY KEY (id),
  CONSTRAINT sedes_lugar_id_fkey FOREIGN KEY (lugar_id) REFERENCES public.lugares(id)
);
CREATE TABLE public.catalogo_motivos_papeleta (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  codigo text NOT NULL UNIQUE,
  nombre text NOT NULL,
  requiere_sustento boolean NOT NULL DEFAULT true,
  orden smallint,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'INACTIVO'::text])),
  intranet_value text NOT NULL UNIQUE,
  CONSTRAINT catalogo_motivos_papeleta_pkey PRIMARY KEY (id)
);
CREATE TABLE public.catalogo_actividades (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  nombre text NOT NULL UNIQUE,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'INACTIVO'::text])),
  CONSTRAINT catalogo_actividades_pkey PRIMARY KEY (id)
);
CREATE TABLE public.catalogo_metas (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  codigo text NOT NULL UNIQUE,
  nombre text NOT NULL,
  orden smallint,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'INACTIVO'::text])),
  CONSTRAINT catalogo_metas_pkey PRIMARY KEY (id)
);
CREATE TABLE public.catalogo_especificas_gasto (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  meta_id uuid NOT NULL,
  codigo text NOT NULL,
  nombre text NOT NULL,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'INACTIVO'::text])),
  CONSTRAINT catalogo_especificas_gasto_pkey PRIMARY KEY (id),
  CONSTRAINT catalogo_especificas_gasto_meta_id_fkey FOREIGN KEY (meta_id) REFERENCES public.catalogo_metas(id)
);
CREATE TABLE public.usuarios_config (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  usuario_sanipes text NOT NULL UNIQUE,
  nombres text NOT NULL DEFAULT 'POR_ACTUALIZAR'::text,
  apellido_paterno text,
  apellido_materno text,
  dni character varying UNIQUE,
  correo text UNIQUE,
  telefono character varying,
  fecha_nacimiento date,
  direccion_domicilio text,
  url_firma text,
  cargo text NOT NULL DEFAULT 'NO_ASIGNADO'::text CHECK (cargo = ANY (ARRAY['CHOFER'::text, 'ASISTENTE_ADMINISTRATIVO'::text, 'COORDINADOR_OSD'::text, 'FISCALIZADOR_SANITARIO'::text, 'NO_ASIGNADO'::text])),
  tipo_contratacion text NOT NULL DEFAULT 'CAS'::text CHECK (tipo_contratacion = ANY (ARRAY['CAS'::text, 'OS'::text, 'CAP'::text, 'PRACTICANTE'::text])),
  rol_sistema text NOT NULL DEFAULT 'USUARIO'::text CHECK (rol_sistema = ANY (ARRAY['USUARIO'::text, 'ADMIN'::text, 'SUPERADMIN'::text])),
  tiene_papeleta boolean NOT NULL DEFAULT true,
  puede_solicitar_caja_chica boolean NOT NULL DEFAULT true,
  jefe_inmediato_id uuid,
  sede_id uuid NOT NULL,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'INACTIVO'::text])),
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  updated_at timestamp with time zone NOT NULL DEFAULT now(),
  created_by uuid,
  updated_by uuid,
  puede_conducir boolean NOT NULL DEFAULT false,
  app_pin character varying,
  CONSTRAINT usuarios_config_pkey PRIMARY KEY (id),
  CONSTRAINT usuarios_config_jefe_inmediato_id_fkey FOREIGN KEY (jefe_inmediato_id) REFERENCES public.usuarios_config(id),
  CONSTRAINT usuarios_config_sede_id_fkey FOREIGN KEY (sede_id) REFERENCES public.sedes(id),
  CONSTRAINT usuarios_config_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.usuarios_config(id),
  CONSTRAINT usuarios_config_updated_by_fkey FOREIGN KEY (updated_by) REFERENCES public.usuarios_config(id)
);
CREATE TABLE public.usuario_credenciales (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  usuario_id uuid NOT NULL,
  tipo text NOT NULL CHECK (tipo = ANY (ARRAY['INTRANET_SANIPES'::text, 'OUTLOOK'::text, 'OTRO'::text])),
  valor_cifrado text NOT NULL,
  algoritmo text NOT NULL DEFAULT 'AES-256-GCM'::text,
  version_clave smallint NOT NULL DEFAULT 1,
  ultima_rotacion timestamp with time zone,
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  updated_at timestamp with time zone NOT NULL DEFAULT now(),
  CONSTRAINT usuario_credenciales_pkey PRIMARY KEY (id),
  CONSTRAINT usuario_credenciales_usuario_id_fkey FOREIGN KEY (usuario_id) REFERENCES public.usuarios_config(id)
);
CREATE TABLE public.vehiculos (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  placa character varying NOT NULL UNIQUE,
  sede_id uuid NOT NULL,
  marca text NOT NULL,
  modelo text NOT NULL,
  anio_fabricacion integer,
  color text,
  tipo_combustible text NOT NULL DEFAULT 'DIESEL'::text CHECK (tipo_combustible = ANY (ARRAY['GASOLINA'::text, 'DIESEL'::text, 'GNV'::text, 'GLP'::text])),
  odometro_inicial integer NOT NULL DEFAULT 0,
  odometro_actual integer NOT NULL DEFAULT 0,
  estado text NOT NULL DEFAULT 'ACTIVO'::text CHECK (estado = ANY (ARRAY['ACTIVO'::text, 'MANTENIMIENTO'::text, 'BAJA'::text])),
  url_soat text,
  fecha_vencimiento_soat date,
  url_tive text,
  url_revision_tecnica text,
  fecha_vencimiento_revision date,
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  updated_at timestamp with time zone NOT NULL DEFAULT now(),
  CONSTRAINT vehiculos_pkey PRIMARY KEY (id),
  CONSTRAINT vehiculos_sede_id_fkey FOREIGN KEY (sede_id) REFERENCES public.sedes(id)
);
CREATE TABLE public.sede_fondo_especifica (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  sede_id uuid NOT NULL,
  especifica_id uuid NOT NULL,
  anio integer NOT NULL CHECK (anio >= 2020),
  fondo_asignado numeric NOT NULL CHECK (fondo_asignado >= 0::numeric),
  estado text NOT NULL DEFAULT 'ABIERTO'::text CHECK (estado = ANY (ARRAY['ABIERTO'::text, 'CERRADO'::text])),
  CONSTRAINT sede_fondo_especifica_pkey PRIMARY KEY (id),
  CONSTRAINT sede_fondo_especifica_sede_id_fkey FOREIGN KEY (sede_id) REFERENCES public.sedes(id),
  CONSTRAINT sede_fondo_especifica_especifica_id_fkey FOREIGN KEY (especifica_id) REFERENCES public.catalogo_especificas_gasto(id)
);
CREATE TABLE public.salidas (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  usuario_id uuid NOT NULL,
  fecha_inicio date NOT NULL,
  hora_inicio time without time zone NOT NULL,
  fecha_fin date NOT NULL,
  hora_fin time without time zone NOT NULL,
  motivo_id uuid NOT NULL,
  objeto_autorizacion text NOT NULL CHECK (length(TRIM(BOTH FROM objeto_autorizacion)) >= 10),
  sustento_origen text NOT NULL DEFAULT 'ARCHIVO_SUBIDO'::text CHECK (sustento_origen = ANY (ARRAY['ARCHIVO_SUBIDO'::text, 'REFERENCIA_TEXTO'::text, 'ANEXO_MOVILIDAD'::text, 'MOVILIDAD_GENERADA'::text, 'CAJA_CHICA_GENERADA'::text])),
  sustento_url text,
  sustento_nombre_archivo text,
  sustento_tamanio_bytes integer CHECK (sustento_tamanio_bytes <= 10485760),
  estado text NOT NULL DEFAULT 'BORRADOR'::text CHECK (estado = ANY (ARRAY['BORRADOR'::text, 'CONFIRMADA'::text, 'CANCELADA'::text])),
  fecha_confirmacion timestamp with time zone,
  fecha_cancelacion timestamp with time zone,
  motivo_cancelacion text,
  intranet_id_pk text,
  intranet_id_visual text,
  intranet_enviada_at timestamp with time zone,
  intranet_eliminada_at timestamp with time zone,
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  updated_at timestamp with time zone NOT NULL DEFAULT now(),
  created_by uuid,
  sustento_referencia_texto text,
  sustento_bucket text,
  CONSTRAINT salidas_pkey PRIMARY KEY (id),
  CONSTRAINT salidas_usuario_id_fkey FOREIGN KEY (usuario_id) REFERENCES public.usuarios_config(id),
  CONSTRAINT salidas_motivo_id_fkey FOREIGN KEY (motivo_id) REFERENCES public.catalogo_motivos_papeleta(id),
  CONSTRAINT salidas_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.usuarios_config(id)
);
CREATE TABLE public.intranet_jobs (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  salida_id uuid NOT NULL,
  accion text NOT NULL CHECK (accion = 'CREAR'::text),
  estado text NOT NULL DEFAULT 'PENDIENTE'::text CHECK (estado = ANY (ARRAY['PENDIENTE'::text, 'PROCESANDO'::text, 'COMPLETADO'::text, 'ERROR'::text])),
  intentos smallint NOT NULL DEFAULT 0,
  max_intentos smallint NOT NULL DEFAULT 3,
  ultimo_error text,
  ultimo_intento_at timestamp with time zone,
  worker_id text,
  tomado_at timestamp with time zone,
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  procesado_at timestamp with time zone,
  CONSTRAINT intranet_jobs_pkey PRIMARY KEY (id),
  CONSTRAINT intranet_jobs_salida_id_fkey FOREIGN KEY (salida_id) REFERENCES public.salidas(id)
);
CREATE TABLE public.servicios_movilidad (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  numero_anexo text UNIQUE,
  conductor_id uuid NOT NULL,
  vehiculo_id uuid NOT NULL,
  solicitante_id uuid NOT NULL,
  fecha_salida date NOT NULL,
  hora_salida_estimada time without time zone NOT NULL,
  hora_retorno_estimada time without time zone NOT NULL,
  lugar_inicio_id uuid NOT NULL,
  lugar_destino_id uuid NOT NULL,
  recorrido_detalle text,
  actividad text NOT NULL,
  justificacion text NOT NULL CHECK (length(TRIM(BOTH FROM justificacion)) >= 10),
  justificacion_no_atendida text,
  url_pdf_anexo01 text,
  hora_salida_real time without time zone,
  hora_retorno_real time without time zone,
  odometro_salida integer CHECK (odometro_salida >= 0),
  odometro_retorno integer CHECK (odometro_retorno >= 0),
  recarga_combustible boolean NOT NULL DEFAULT false,
  cantidad_galones numeric CHECK (cantidad_galones > 0::numeric),
  numero_vale text,
  odometro_recarga integer CHECK (odometro_recarga >= 0),
  nivel_combustible_llegada text CHECK (nivel_combustible_llegada = ANY (ARRAY['RESERVA'::text, '1/4'::text, '1/2'::text, '3/4'::text, 'LLENO'::text])),
  observaciones_chofer text,
  estado text NOT NULL DEFAULT 'SOLICITADO'::text CHECK (estado = ANY (ARRAY['SOLICITADO'::text, 'EN_RUTA'::text, 'FINALIZADO'::text, 'CANCELADO'::text])),
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  updated_at timestamp with time zone NOT NULL DEFAULT now(),
  created_by uuid,
  pdf_estado text NOT NULL DEFAULT 'PENDIENTE'::text CHECK (pdf_estado = ANY (ARRAY['PENDIENTE'::text, 'PROCESANDO'::text, 'GENERADO'::text, 'ERROR'::text])),
  pdf_intentos smallint NOT NULL DEFAULT 0,
  pdf_ultimo_error text,
  pdf_generado_at timestamp with time zone,
  sustento_salida_url text,
  sustento_salida_bucket text,
  sustento_salida_nombre text,
  CONSTRAINT servicios_movilidad_pkey PRIMARY KEY (id),
  CONSTRAINT servicios_movilidad_conductor_id_fkey FOREIGN KEY (conductor_id) REFERENCES public.usuarios_config(id),
  CONSTRAINT servicios_movilidad_vehiculo_id_fkey FOREIGN KEY (vehiculo_id) REFERENCES public.vehiculos(id),
  CONSTRAINT servicios_movilidad_solicitante_id_fkey FOREIGN KEY (solicitante_id) REFERENCES public.usuarios_config(id),
  CONSTRAINT servicios_movilidad_lugar_inicio_id_fkey FOREIGN KEY (lugar_inicio_id) REFERENCES public.lugares(id),
  CONSTRAINT servicios_movilidad_lugar_destino_id_fkey FOREIGN KEY (lugar_destino_id) REFERENCES public.lugares(id),
  CONSTRAINT servicios_movilidad_created_by_fkey FOREIGN KEY (created_by) REFERENCES public.usuarios_config(id)
);
CREATE TABLE public.servicio_movilidad_comisionados (
  id uuid NOT NULL DEFAULT uuid_generate_v4(),
  servicio_movilidad_id uuid NOT NULL,
  comisionado_id uuid NOT NULL,
  salida_id uuid,
  es_conductor boolean NOT NULL DEFAULT false,
  created_at timestamp with time zone NOT NULL DEFAULT now(),
  CONSTRAINT servicio_movilidad_comisionados_pkey PRIMARY KEY (id),
  CONSTRAINT servicio_movilidad_comisionados_servicio_movilidad_id_fkey FOREIGN KEY (servicio_movilidad_id) REFERENCES public.servicios_movilidad(id),
  CONSTRAINT servicio_movilidad_comisionados_comisionado_id_fkey FOREIGN KEY (comisionado_id) REFERENCES public.usuarios_config(id),
  CONSTRAINT servicio_movilidad_comisionados_salida_id_fkey FOREIGN KEY (salida_id) REFERENCES public.salidas(id)
);